<template>
  <ElSelect
    v-model="props.data[props.field.name]"
    :placeholder="placeholderText"
    clearable
    :filterable="filterable"
	:multiple="props.field.multiple=='1'"
	:empty-text="placeholderText"
	:no-match-text="placeholderText"
	:empty-values="validEmptyValues"
    style="width: 100%"
    @visible-change="handleDropdownVisible"
	@clear="handleClear"
  >
    <ElOption
	  v-if="fetch==true"
      v-for="(option, index) in fieldOptions"
      :key="option[props.option.value] ?? index"
      :label="option[props.option.label]"
      :value="option[props.option.value]"
    />
	
	<ElOption
	  v-else
	  v-for="(option, index) in fieldOptions"
	  :key="option.value ?? index"
	  :label="option.cnLabel"
	  :value="option.value"
	  :disabled="option.status === '1'"
	/>
  </ElSelect>
</template>

<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import type { PropType } from 'vue'
import { DictService } from '@/api/sys/dictApi'


const emit = defineEmits(['update:value'])

const props = defineProps({
  field: {
    type: Object as PropType<Record<string, any>>,
    required: true,
    default: () => ({}),
    validator: (field: any) => {
      if (field.mapping === 'dict' && !field.mappingKey) {
        console.warn('当使用字典映射时，必须提供 mappingKey')
        return false
      }
      return true
    }
  },
  data: {
    type: Object as PropType<Record<string, any>>,
    default: () => ({})
  },
  fetchOptions: {
  	type: Function as PropType<(params?: any) => Promise<any>>,
  	required: false
  },
  option: {
    type: Object as PropType<Record<string, any>>,
    default: () => ({})
  },
})

// 计算属性
const placeholderText = computed(() => {
  return props.field.placeholder || `请选择${props.field.label || ''}`
})

const clearable = computed(() => {
  return props.field.clearable ?? true
})

const filterable = computed(() => {
  return props.field.filterable=='0'
})

// 选项数据
const fieldOptions = ref<any[]>([])
const loading = ref(false)
const dropdownVisible = ref(false)
const fetch=ref<boolean>(false)
// 获取选择项数据
const getSelectOptions = async () => {
  try {
    if (props.field.mapping === 'dict' && props.field.mappingKey) {
      loading.value = true
      const data = await DictService.getSelectOptions(props.field.mappingKey)
      fieldOptions.value = Array.isArray(data) ? data : []
    } else {
      fieldOptions.value = Array.isArray(props.field.options) 
        ? props.field.options 
        : []
    }
  } catch (error) {
    console.error('获取选项数据失败:', error)
    fieldOptions.value = []
  } finally {
    loading.value = false
  }
}

// 监听下拉框可见状态变化
const handleDropdownVisible = (visible: boolean) => {
  dropdownVisible.value = visible
  // 如果下拉框打开且选项为空，重新获取数据
  if (visible && fieldOptions.value.length === 0) {
    getSelectOptions()
  }
}

// 处理 empty-values
const validEmptyValues = computed(() => {
  const values = new Set<any>([null, undefined, '']) // 默认空值
  // 添加配置的空值
  if (props.field?.emptyValues) {
    props.field.emptyValues.split(',').forEach(item => {
      const trimmed = item.trim()
      if (trimmed === 'null') values.add(null)
      else if (trimmed === 'undefined') values.add(undefined)
      else if (trimmed !== '') values.add(trimmed)
    })
  }
  // 确保defaultValue在emptyValues中
  if (props.field?.defaultValue !== undefined) {
    values.add(props.field.defaultValue)
  }
  return Array.from(values)
})

const handleClear=()=>{
	props.data[props.field.name]=props.field.defaultValue;
}

// 双向绑定值
const fieldValue = computed({
  get: () => props.data[props.field.name],
  set: (value) => {
    emit('update:value', value)
  }
})

const getFetchOptions = async (params?: any) => {
	if(props.fetchOptions){
		loading.value = true
		try {
		  const data = await props.fetchOptions(params)
		  fieldOptions.value = Array.isArray(data) ? data : []
		} catch (error) {
		  console.error('数据加载失败', error)
		} finally {
			loading.value = false
			fetch.value=true;
		}
  }
}

// 监听field.mappingKey变化重新获取数据
watch(
  () => props.field.mappingKey,
  (newKey, oldKey) => {
    if (newKey && newKey !== oldKey) {
      getSelectOptions()
    }
  }
)

// 初始化时获取数据
watch(
  () => props.field.mapping,
  getSelectOptions,
  { immediate: true }
)

watch(
  () => props.fetchOptions,
	getFetchOptions,
  { immediate: true }
)
</script>